
/** libObfuscate CBC wrappers */
void XOR16(const unsigned char *, const unsigned char *, unsigned char *);
void lob_encrypt(const unsigned char *, unsigned char *, const unsigned char *, const unsigned char *, int, wchar_t);
void lob_decrypt(const unsigned char *, unsigned char *, const unsigned char *, const unsigned char *, int, wchar_t);
/** OpenSSL AES CBC  */
int oss_encrypt(const unsigned char *, int, const unsigned char *, const unsigned char *, unsigned char *);
int oss_decrypt(const unsigned char *, int, const unsigned char *, const unsigned char *, unsigned char *);

#pragma pack(1)
 typedef struct FC_HDR_CLEAR
 {
  /**  "flxcrypt"  */
  unsigned char   magic[8]; 
  unsigned char   salt[128];
  unsigned char   flags[4];
  UINT32          blocksize;
  /**
   * size at this point is 8 + 128 + 4 + 4 = 140
   */
 } FCHDR, *pFCHDR;

 typedef struct Differencing_Disk_Keys
 {
   FCHDR            clear;
   wchar_t        * szImage;
   unsigned char  * keys;              /* up-to 3, 256 bit keys */
   wchar_t          cascade[3];        /* cipher cascade        */
   struct Differencing_Disk_Keys *next;   
 } DDK, *pDDK;
#pragma pack()

#ifdef __fcrypt__
 typedef void (*pfnERR_load_crypto_strings)(void);
 typedef void (*pfnOpenSSL_add_all_algorithms)(void);
 typedef void (*pfnOPENSSL_config)(unsigned char *);
 typedef void (*pfnEVP_cleanup)(void);
 typedef void (*pfnERR_free_strings)(void);
 typedef int  (*pfnEVP_EncryptInit_ex)(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv);
 typedef int  (*pfnEVP_EncryptUpdate)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl);
 typedef int  (*pfnEVP_EncryptFinal_ex)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
 typedef void (*pfnEVP_CIPHER_CTX_free)(EVP_CIPHER_CTX *a);
 typedef int  (*pfnEVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX *c, int pad);
 typedef int  (*pfnEVP_DecryptInit_ex)(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv);
 typedef int  (*pfnEVP_DecryptUpdate)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl);
 typedef int  (*pfnEVP_DecryptFinal_ex)(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
 typedef EVP_CIPHER_CTX* (*pfnEVP_CIPHER_CTX_new)(void);
 typedef const EVP_CIPHER* (*pfnEVP_aes_256_cbc)(void);
 typedef unsigned char * (*pfnRIPEMD160)(const unsigned char *d, unsigned long n, unsigned char *md);
 typedef int (*pfnRIPEMD160_Init)(RIPEMD160_CTX *c);
 typedef int (*pfnRIPEMD160_Update)(RIPEMD160_CTX *c, const void *data, unsigned long len);
 typedef int (*pfnRIPEMD160_Final)(unsigned char *md, RIPEMD160_CTX *c);
 typedef int (*pfnPKCS5_PBKDF2_HMAC)(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out);
 typedef const EVP_MD * (*pfnEVP_ripemd160)(void);
 typedef const EVP_MD * (*pfnEVP_sha512)(void);
 typedef const EVP_MD * (*pfnEVP_sha1)(void);  
 typedef int (*pfnRAND_bytes)(unsigned char *buf, int num);

 pfnOpenSSL_add_all_algorithms  pOpenSSL_add_all_algorithms;
 pfnEVP_CIPHER_CTX_set_padding  pEVP_CIPHER_CTX_set_padding; 
 pfnERR_load_crypto_strings     pERR_load_crypto_strings;
 pfnOPENSSL_config              pOPENSSL_config;
 pfnERR_free_strings            pERR_free_strings;
 pfnEVP_EncryptUpdate           pEVP_EncryptUpdate; 
 pfnEVP_EncryptInit_ex          pEVP_EncryptInit_ex;
 pfnEVP_EncryptFinal_ex         pEVP_EncryptFinal_ex;
 pfnEVP_CIPHER_CTX_free         pEVP_CIPHER_CTX_free;
 pfnEVP_DecryptInit_ex          pEVP_DecryptInit_ex;
 pfnEVP_DecryptUpdate           pEVP_DecryptUpdate;
 pfnEVP_DecryptFinal_ex         pEVP_DecryptFinal_ex;
 pfnEVP_CIPHER_CTX_new          pEVP_CIPHER_CTX_new;
 pfnEVP_aes_256_cbc             pEVP_aes_256_cbc;
 pfnEVP_cleanup                 pEVP_cleanup; 
 pfnRIPEMD160_Init              pRIPEMD160_Init;
 pfnRIPEMD160_Update            pRIPEMD160_Update;
 pfnRIPEMD160_Final             pRIPEMD160_Final;
 pfnPKCS5_PBKDF2_HMAC           pPKCS5_PBKDF2_HMAC;
 pfnEVP_ripemd160               pEVP_ripemd160;
 pfnEVP_sha512                  pEVP_sha512;
 pfnEVP_sha1                    pEVP_sha1;
 pfnRIPEMD160                   pRIPEMD160;
 pfnRAND_bytes                  pRAND_bytes;
#endif